﻿using ELF.Infrastructure.Data;
using Interfaces;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Repositories;
using Services;
using Utils;

namespace ELF.Modules;

[DependsOn(typeof(DomainModule))]
[DependsOn(typeof(ElfDddDataModule))]
public class InfrastructureModule : BaseModule
{
    public override Task ConfigureServicesAsync(IHostApplicationBuilder builder)
    {
        IConfiguration configuration = builder.Configuration;
        var services = builder.Services;

        builder.AddRedisClient(connectionName: "cache");
        services.AddMemoryCache();

        var connectionString = configuration.GetConnectionString("identityserviceDb");
        Guard.Against.Null(connectionString, message: "Connection string 'identityserviceDb' not found.");

        var version = MySqlServerVersion.LatestSupportedServerVersion; //最近版本
        if (!EF.IsDesignTime)
        {
            Console.WriteLine(version.ToString());
            version = ServerVersion.AutoDetect(connectionString);
        }

        services.AddAppDbContext<ApplicationDbContext>((sp, options) =>
        {
            options.UseMySql(connectionString, version);
            //注册OpenIddict所需的实体集。
            //注意：如果需要替换默认的OpenIddict实体，请使用通用重载。
            options.UseOpenIddict();
        });
        services.AddScoped<DbContext, ApplicationDbContext>();

        // 配置OpenIddict
        services.AddOpenIddict()
            // 配置 OpenIddict 核心组件
            .AddCore(options =>
            {
                options.UseEntityFrameworkCore()
                    .UseDbContext<ApplicationDbContext>();
            });
        services.AddSingleton(TimeProvider.System);
        services.AddScoped<IPasswordEncryptor, Md5PasswordEncryptor>();
        services.AddScoped<IPermissionRepository, PermissionRepository>();
        services.AddScoped<IRoleRepository, RoleRepository>();
        services.AddScoped<IUserRepository, UserRepository>();
        //Todo
        services.AddScoped<IIdentityService, IdentityService>();
        return base.ConfigureServicesAsync(builder);
    }
}
